﻿using mozhi.smarterp.Finance.Accounts;
using mozhi.smarterp.Finance.Accounts.Repository;
using mozhi.smarterp.Finance.Basedatas.Repository;
using mozhi.smarterp.Finance.Querys;
using Mozhi.Abp.Core.Extensions;
using Mozhi.Abp.Domain.BasicData;
using Mozhi.Abp.Domain.BasicData.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Domain.Services;
using Volo.Abp.Guids;
using Volo.Abp.Uow;

namespace mozhi.smarterp.Finance.Basedatas.Services
{
    public class DimensionGroupValueManager : DomainService
    {
        private IDimensionGroupValueRepository _repository;
        private IGuidGenerator _guidGenerator;
        private ITagRepository _tagRepository;
        private IAccountDimensionRepository _accountDimensionRepository;
        private ICustomerRepository _customerRepository;
        public DimensionGroupValueManager(IDimensionGroupValueRepository repository, IGuidGenerator guidGenerator, 
            IServiceProvider serviceProvider)
        {
            _repository = repository;
            _guidGenerator = guidGenerator;
            _tagRepository = serviceProvider.GetService(typeof(ITagRepository)) as ITagRepository;
            _accountDimensionRepository = serviceProvider.GetService(typeof(IAccountDimensionRepository)) as IAccountDimensionRepository;
            _customerRepository = serviceProvider.GetService(typeof(ICustomerRepository)) as ICustomerRepository;
        }


        public async Task<Guid> GetDimensionGroupValueId(DimensionGroupValuePageQuery query)
        {
            var dimensionGroupValues = await _repository.GetAsync(query);

            if (dimensionGroupValues.Count == 0)
            {
                //需要新增一条空白维度的数据
                var dimensionGroupValue = new DimensionGroupValue(_guidGenerator.Create());

                if (query.Items != null)
                {
                    foreach (var itemDto in query.Items)
                    {
                        var item = new DimensionGroupValueItem(_guidGenerator.Create(), dimensionGroupValue.Id, itemDto.DataSourceType, itemDto.TagId, itemDto.Value);

                        dimensionGroupValue.Items.Add(item);
                    }
                }
                dimensionGroupValue.ChangeUniqueValue();
                dimensionGroupValue = await _repository.InsertAsync(dimensionGroupValue , true);

                dimensionGroupValues.Add(dimensionGroupValue);
            }

            return dimensionGroupValues.First().Id;
        }

        public async Task<List<DimensionGroupValue>> GetDimensionGroupValues(List<Guid> dimensionValueGroupIds)
        {
            var result = new List<DimensionGroupValue>();

            if (dimensionValueGroupIds == null || dimensionValueGroupIds.Count == 0)
                return result;

            result = await _repository.FindAsync(new DimensionGroupValuePageQuery() { Ids = dimensionValueGroupIds, PageIndex = 1, PageSize = int.MaxValue });

            if (result.Count == 0)
                return result;

            var dimensionValueItems = result.Where(x => x.Items != null && x.Items.Count > 0).Select(x => x.Items).ToList().Join();

            var tagDimensionValueItems = dimensionValueItems.Where(x => x.DataSourceType == Enums.DataSourceType.Tag && x.Value != null).ToList();

            if (tagDimensionValueItems.Count > 0)
            {
                var tagIds = tagDimensionValueItems.Where(x => x.TagId.HasValue).Select(x => x.TagId.Value).Distinct().ToList();

                var tags = await _tagRepository.FindAsync(new PageQuery() { Ids = tagIds, IncludeDetail = true, PageIndex = 1, PageSize = int.MaxValue });

                foreach (var tagItem in tagDimensionValueItems)
                {
                    var matchTag = tags.FirstOrDefault(x => x.Id == tagItem.TagId);

                    if (matchTag == null)
                        continue;

                    if (matchTag.Type != Enums.TagType.List)
                    {
                        //不是列表的字段直接给值
                        tagItem.Label = tagItem.Value;
                        continue;
                    }

                    var matchTagItem = matchTag.Items?.FirstOrDefault(x => x.Id.ToString() == tagItem.Value);

                    tagItem.Label = matchTagItem?.Name;
                }
            }

            var customerDimensionValueItems = dimensionValueItems.Where(x => x.DataSourceType == Enums.DataSourceType.Customer && x.Value != null).ToList();

            if (customerDimensionValueItems.Count > 0)
            {
                var ids = customerDimensionValueItems.Where(x => !x.Value.IsNullOrEmpty()).Select(x => Guid.Parse(x.Value)).Distinct().ToList();

                var customers = new List<Customer>(); //await _customerRepository.FindAsync(new BaseDataPageQuery() { Ids = ids, IncludeDetail = true, PageIndex = 1, PageSize = int.MaxValue });

                foreach (var customerItem in customerDimensionValueItems)
                {
                    var matchCustomer = customers.FirstOrDefault(x => x.Id.ToString() == customerItem.Value);

                    if (matchCustomer == null)
                        continue;

                    customerItem.Label = matchCustomer.Code +" "+ matchCustomer.Name;
                }
            }

            return result;
        }

        /// <summary>
        /// 校验核算维度
        /// </summary>
        /// <param name="dimensionItems"></param>
        /// <param name="dimensionGroupValueItems"></param>
        public async Task ValidateDimensionGroupValue(List<AccountDimensionItem> dimensionItems , List<DimensionGroupValueItem> dimensionGroupValueItems)
        {
            if (dimensionItems == null || dimensionItems.Count == 0)
                return;

            var dimensionIds = dimensionItems.Select(x => x.DimensionId).ToList();

            var dimensions = await _accountDimensionRepository.FindAsync(new PageQuery() { Ids = dimensionIds, PageIndex = 1, PageSize = int.MaxValue });

            foreach (var dimensionItem in dimensionItems)
            {
                var matchDimension = dimensions.FirstOrDefault(x=>x.Id == dimensionItem.DimensionId);

                if (matchDimension == null)
                    continue;

                if (matchDimension.Activated == false)
                    throw new UserFriendlyException($"核算维度:{matchDimension.Name}已禁用", "100000");

                //非必填就不需要校验核算维度值了
                if (!dimensionItem.IsRequire)
                    continue;

                var matchDimensionGroupValue = dimensionGroupValueItems.FirstOrDefault(x=>x.DataSourceType == matchDimension.DataSourceType && x.TagId == matchDimension.TagId);

                if(matchDimensionGroupValue==null || matchDimensionGroupValue.Value.IsNullOrEmpty())
                    throw new UserFriendlyException($"核算维度:{matchDimension.Name}为必填项", "100000");
            }
        }
    }
}
